package client

import (
	"io"
	"log"
	"net"
	"test_chat/ptotocol"
	"time"
)

type TcpClient struct {
	conn      net.Conn
	cmdReader *ptotocol.Reader
	cmdWriter *ptotocol.Writer
	name      string
	incoming  chan ptotocol.MessCmd
}

func NewTcpClient() *TcpClient {
	return &TcpClient{
		incoming: make(chan ptotocol.MessCmd),
	}
}

func (c *TcpClient) Dial(address string) error {
	log.Println("Start to dial client", address)
	conn, err := net.Dial("tcp", address)
	if err == nil {
		c.conn = conn
	} else {
		log.Println("Dial error")
		return err
	}
	c.cmdReader = ptotocol.NewReader(conn)
	c.cmdWriter = ptotocol.NewWriter(conn)
	return err
}

func (c *TcpClient) Start() {
	log.Println("Start to start client")
	time.Sleep(4 * time.Second)
	for {
		cmd, err := c.cmdReader.Read()
		if err != nil && err == io.EOF {
			log.Println("client is closed")
		}

		if cmd != nil {
			switch v := cmd.(type) {
			case ptotocol.MessCmd:
				c.incoming <- v
			default:
				log.Println("cmd type error")
			}
		}

	}
}

func (c *TcpClient) Close() {
	c.conn.Close()
}

func (c *TcpClient) Send(command interface{}) error {
	return c.cmdWriter.Write(command)
}

func (c *TcpClient) SendName(name string) error {
	return c.Send(ptotocol.NameCmd{name})
}

func (c *TcpClient) SendMes(msg string) error {
	return c.Send(ptotocol.SendCmd{
		Msg: msg,
	})
}

func (c *TcpClient) InComing() chan ptotocol.MessCmd {
	return c.incoming

}
